<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\MjzjReviewer;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Exception;

class MjzjCrawlerService
{
    /**
     * API基础URL
     */
    private const BASE_URL = 'https://data.mjzj.com/api/Exposury/Search';

    /**
     * 默认请求头
     */
    private array $defaultHeaders = [
        'Accept' => 'application/json, text/plain, */*',
        'Accept-Language' => 'zh-CN,zh;q=0.9',
        'Connection' => 'keep-alive',
        'Origin' => 'https://mjzj.com',
        'Referer' => 'https://mjzj.com/',
        'Sec-Fetch-Dest' => 'empty',
        'Sec-Fetch-Mode' => 'cors',
        'Sec-Fetch-Site' => 'same-site',
        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
        'sec-ch-ua' => '"Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"',
        'sec-ch-ua-mobile' => '?0',
        'sec-ch-ua-platform' => '"Windows"',
    ];

    /**
     * 搜索评论者数据
     */
    public function searchReviewers(array $params = []): array
    {
        $defaultParams = [
            'keywords' => '',
            'market' => '',
            'type' => 'ReviewerExposure',
            'sortType' => 1,
            'size' => 20,
            'position' => 0,
        ];

        $params = array_merge($defaultParams, $params);

        try {
            $response = $this->makeRequest($params);
            
            if ($response->successful()) {
                $data = $response->json();
                return $this->processResponse($data, $params);
            } else {
                Log::error('MJZJ API请求失败', [
                    'status' => $response->status(),
                    'body' => $response->body(),
                    'params' => $params
                ]);
                return [];
            }
        } catch (Exception $e) {
            Log::error('MJZJ爬虫异常', [
                'message' => $e->getMessage(),
                'params' => $params,
                'trace' => $e->getTraceAsString()
            ]);
            return [];
        }
    }

    /**
     * 批量爬取数据
     */
    public function crawlBatch(array $keywords, int $batchSize = 20): array
    {
        $results = [];
        
        foreach ($keywords as $keyword) {
            Log::info("开始爬取关键词: {$keyword}");
            
            $position = 0;
            $hasMore = true;
            
            while ($hasMore) {
                $params = [
                    'keywords' => $keyword,
                    'size' => $batchSize,
                    'position' => $position,
                ];
                
                $data = $this->searchReviewers($params);
                
                if (empty($data)) {
                    $hasMore = false;
                } else {
                    $results[$keyword][] = $data;
                    $position += $batchSize;
                    
                    // 防止过于频繁的请求
                    sleep(1);
                }
                
                // 限制每个关键词最多爬取500条记录
                if ($position >= 500) {
                    $hasMore = false;
                }
            }
        }
        
        return $results;
    }

    /**
     * 发起API请求
     */
    private function makeRequest(array $params): Response
    {
        return Http::withHeaders($this->defaultHeaders)
            ->timeout(30)
            ->get(self::BASE_URL, $params);
    }

    /**
     * 处理API响应数据
     */
    private function processResponse(array $data, array $params): array
    {
        if (!isset($data['data']) || !is_array($data['data'])) {
            return [];
        }

        $processed = [];
        
        foreach ($data['data'] as $item) {
            $reviewerData = $this->transformData($item, $params);
            
            if ($reviewerData) {
                // 保存到数据库
                $reviewer = MjzjReviewer::findOrCreateByReviewerId(
                    $reviewerData['reviewer_id'],
                    $reviewerData
                );
                
                $processed[] = $reviewer->toArray();
            }
        }
        
        return $processed;
    }

    /**
     * 转换数据格式
     */
    private function transformData(array $item, array $params): ?array
    {
        // 根据实际API返回的数据结构调整字段映射
        $reviewerId = $item['id'] ?? $item['reviewer_id'] ?? uniqid('mjzj_');
        
        if (empty($reviewerId)) {
            return null;
        }

        return [
            'reviewer_id' => (string) $reviewerId,
            'name' => $item['name'] ?? $item['reviewer_name'] ?? '未知',
            'avatar' => $item['avatar'] ?? $item['avatar_url'] ?? null,
            'platform' => $item['platform'] ?? 'MJZJ',
            'country' => $item['country'] ?? $item['location'] ?? null,
            'rating' => (float) ($item['rating'] ?? $item['score'] ?? 0),
            'review_count' => (int) ($item['review_count'] ?? $item['reviews'] ?? 0),
            'follower_count' => (int) ($item['follower_count'] ?? $item['followers'] ?? 0),
            'email' => $item['email'] ?? $item['contact_email'] ?? null,
            'contact_info' => $item['contact_info'] ?? $item['contact'] ?? null,
            'description' => $item['description'] ?? $item['bio'] ?? null,
            'keywords' => $params['keywords'] ?? null,
            'market' => $params['market'] ?? null,
            'exposure_score' => (float) ($item['exposure_score'] ?? $item['exposure'] ?? 0),
            'last_active' => isset($item['last_active']) ? 
                date('Y-m-d H:i:s', strtotime($item['last_active'])) : null,
            'raw_data' => $item,
        ];
    }

    /**
     * 获取统计信息
     */
    public function getStats(): array
    {
        return [
            'total_reviewers' => MjzjReviewer::count(),
            'active_reviewers' => MjzjReviewer::whereNotNull('last_active')
                ->where('last_active', '>=', now()->subDays(30))
                ->count(),
            'top_platforms' => MjzjReviewer::selectRaw('platform, COUNT(*) as count')
                ->groupBy('platform')
                ->orderByDesc('count')
                ->limit(10)
                ->get(),
            'avg_rating' => MjzjReviewer::avg('rating'),
            'avg_reviews' => MjzjReviewer::avg('review_count'),
        ];
    }
} 